package com.example.shuiyin.config;

import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.util.StringUtils;

import javax.sql.DataSource;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.sql.Connection;

@Configuration
@Slf4j
public class DataSourceConfig {

    // 对这些属性默认值进行设置，防止配置文件未加载时抛出异常
    @Value("${spring.datasource.url:jdbc:mysql://localhost:3306/shuiyin?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true}")
    private String url;

    @Value("${spring.datasource.username:root}")
    private String username;

    @Value("${spring.datasource.password:}")
    private String password;

    @Value("${spring.datasource.driver-class-name:com.mysql.cj.jdbc.Driver}")
    private String driverClassName;

    @Value("${spring.datasource.hikari.maximum-pool-size:15}")
    private int maximumPoolSize;

    @Value("${spring.datasource.hikari.minimum-idle:5}")
    private int minimumIdle;

    @Value("${spring.datasource.hikari.connection-timeout:30000}")
    private long connectionTimeout;

    @Bean
    @Primary
    public DataSource dataSource() {
        log.info("初始化数据源...");
        
        // 先检查MySQL服务是否可用
        if (!isMysqlRunning("localhost", 3306)) {
            log.error("MySQL服务未运行，将使用空数据源模式启动");
            return createEmptyDataSource();
        }
        
        // 使用配置文件中的值
        log.info("数据库URL: {}", url);
        log.info("数据库驱动: {}", driverClassName);
        log.info("数据库用户名: {}", username);
        log.info("最大连接池大小: {}", maximumPoolSize);
        
        try {
            HikariDataSource dataSource = new HikariDataSource();
            dataSource.setJdbcUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            dataSource.setDriverClassName(driverClassName);
            dataSource.setMaximumPoolSize(maximumPoolSize);
            dataSource.setMinimumIdle(minimumIdle);
            dataSource.setConnectionTimeout(connectionTimeout);
            
            // 添加额外配置以提高稳定性
            dataSource.setAutoCommit(true);
            dataSource.setIdleTimeout(60000);
            dataSource.setMaxLifetime(1800000);
            dataSource.setConnectionTestQuery("SELECT 1");
            dataSource.setPoolName("ShuiyinHikariCP");
            
            // 连接初始化失败重试
            dataSource.setInitializationFailTimeout(10000);
            // 连接泄漏检测
            dataSource.setLeakDetectionThreshold(30000);
            
            // 验证数据源连接是否可用
            try (Connection connection = dataSource.getConnection()) {
                log.info("数据库连接测试成功: {}", connection.getMetaData().getURL());
            } catch (Exception e) {
                log.warn("数据库连接测试失败: {}", e.getMessage());
            }
            
            log.info("数据源初始化完成");
            return dataSource;
        } catch (Exception e) {
            log.error("创建数据源时发生错误: {}", e.getMessage(), e);
            log.warn("将使用备用数据源创建方式");
            
            // 尝试使用备用方式创建数据源
            return createBackupDataSource(url, username, password, driverClassName);
        }
    }
    
    private DataSource createBackupDataSource(String url, String username, String password, String driverClassName) {
        try {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            dataSource.setDriverClassName(driverClassName);
            
            log.info("备用数据源创建成功");
            return dataSource;
        } catch (Exception e) {
            log.error("备用数据源创建失败: {}", e.getMessage(), e);
            return createEmptyDataSource();
        }
    }
    
    private DataSource createEmptyDataSource() {
        log.warn("创建空数据源，应用可能无法正常工作");
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl("jdbc:h2:mem:empty;DB_CLOSE_DELAY=-1");
        dataSource.setUsername("sa");
        dataSource.setPassword("");
        dataSource.setDriverClassName("org.h2.Driver");
        return dataSource;
    }
    
    private boolean isMysqlRunning(String host, int port) {
        try (Socket socket = new Socket()) {
            socket.connect(new InetSocketAddress(host, port), 1000);
            log.info("MySQL服务检测：运行中 ({}:{})", host, port);
            return true;
        } catch (Exception e) {
            log.error("MySQL服务检测：未运行 ({}:{})", host, port);
            return false;
        }
    }
} 